# gui/timer_tab.py
from __future__ import annotations
from typing import Callable, Optional, List
import tkinter as tk
from tkinter import ttk, messagebox

from timer import Timer
from database import (
    init_db,
    save_timer as db_save_timer,
    get_timers,
    clear_timers as db_clear_timers,
    delete_timer_by_id,
)


class TimerTab:
    """Timer page UI + interactions (start/pause/stop/save/list/delete)."""

    def __init__(
        self, parent, root: tk.Tk, on_data_changed: Optional[Callable[[], None]] = None
    ) -> None:
        self.parent = parent
        self.root = root
        self.on_data_changed = on_data_changed
        self.frame = ttk.Frame(self.parent)

        # Business state
        init_db()
        self.timer = Timer(self.root)
        self.timer.set_callbacks(self._update_display, self._on_complete)
        self.current_seconds: float = 0.0

        # --- UI blocks ---
        self._build_mode_panel()
        self._build_display_panel()
        self._build_toolbar()
        self._build_countdown_panel()
        self._build_list_panel()

        # Defaults
        self._update_mode_panels()
        self._refresh_timer_list()

        # Bindings
        for entry in (self.hours_entry, self.minutes_entry, self.seconds_entry):
            entry.bind("<FocusIn>", self._on_entry_focus)
            entry.bind("<Key>", self._validate_numeric_key)

    # ================= UI =================
    def _build_mode_panel(self) -> None:
        self.mode_frame = ttk.LabelFrame(self.frame, text="计时模式")
        self.mode_frame.pack(pady=10, padx=10, fill=tk.X)
        self.timer_mode = tk.StringVar(value="countup")
        modes = ("正计时", "倒计时")
        values = ("countup", "countdown")
        self.r1 = ttk.Radiobutton(
            self.mode_frame,
            text=modes[0],
            variable=self.timer_mode,
            value=values[0],
            command=self._update_mode_panels,
        )
        self.r2 = ttk.Radiobutton(
            self.mode_frame,
            text=modes[1],
            variable=self.timer_mode,
            value=values[1],
            command=self._update_mode_panels,
        )
        self.r1.pack(side=tk.LEFT, padx=5)
        self.r2.pack(side=tk.LEFT, padx=5)

    def _build_display_panel(self) -> None:
        self.display_frame = ttk.Frame(self.frame)
        self.display_frame.pack(padx=10, pady=5, fill=tk.X)
        self.display_frame.columnconfigure(0, weight=1)
        self.display_frame.columnconfigure(1, weight=1)
        self.time_label = ttk.Label(
            self.display_frame, text="00:00:00", font=("Arial", 32), anchor=tk.CENTER
        )
        self.status_label = ttk.Label(self.display_frame, text="就绪", anchor=tk.CENTER)
        self.time_label.grid(row=0, column=0, columnspan=2, pady=5, sticky="ew")
        self.status_label.grid(row=1, column=0, columnspan=2, sticky="ew")

    def _build_toolbar(self) -> None:
        self.control_frame = ttk.Frame(self.frame)
        self.control_frame.pack(fill=tk.X, padx=10, pady=5)
        self.start_btn = ttk.Button(
            self.control_frame, text="开始", command=self.start_timer
        )
        self.pause_btn = ttk.Button(
            self.control_frame, text="暂停", state=tk.DISABLED, command=self.pause_timer
        )
        self.stop_btn = ttk.Button(
            self.control_frame, text="停止", state=tk.DISABLED, command=self.stop_timer
        )
        self.save_btn = ttk.Button(
            self.control_frame, text="保存", command=self.save_timer
        )
        self.delete_btn = ttk.Button(
            self.control_frame, text="单个删除", command=self.delete_timer
        )
        self.clear_btn = ttk.Button(
            self.control_frame, text="全部清空", command=self.clear_timers
        )
        self.refresh_btn = ttk.Button(
            self.control_frame, text="刷新", command=self._refresh_timer_list
        )
        for w in (
            self.start_btn,
            self.pause_btn,
            self.stop_btn,
            self.save_btn,
            self.delete_btn,
            self.clear_btn,
            self.refresh_btn,
        ):
            w.pack(side=tk.LEFT, padx=4)

    def _build_countdown_panel(self) -> None:
        self.countdown_frame = ttk.LabelFrame(self.frame, text="倒计时设置")
        self.countdown_frame.pack(padx=10, pady=5, fill=tk.X)
        self.hours_entry = ttk.Entry(self.countdown_frame, width=5)
        self.minutes_entry = ttk.Entry(self.countdown_frame, width=5)
        self.seconds_entry = ttk.Entry(self.countdown_frame, width=5)
        ttk.Label(self.countdown_frame, text="小时").grid(row=0, column=0)
        self.hours_entry.grid(row=0, column=1, padx=5)
        ttk.Label(self.countdown_frame, text="分钟").grid(row=0, column=2)
        self.minutes_entry.grid(row=0, column=3, padx=5)
        ttk.Label(self.countdown_frame, text="秒").grid(row=0, column=4)
        self.seconds_entry.grid(row=0, column=5, padx=5)

    def _build_list_panel(self) -> None:
        self.list_frame = ttk.LabelFrame(self.frame, text="保存的计时")
        self.list_frame.pack(padx=10, pady=8, fill=tk.BOTH, expand=True)
        self.timer_tree = ttk.Treeview(
            self.list_frame,
            columns=("time", "created_at"),
            show="headings",
            height=6,
            selectmode="extended",
        )
        self.timer_tree.heading("time", text="时长")
        self.timer_tree.heading("created_at", text="创建时间")
        self.timer_tree.column("time", width=120, anchor=tk.CENTER)
        self.timer_tree.column("created_at", width=180, anchor=tk.CENTER)
        self.timer_tree.pack(fill=tk.BOTH, expand=True, side=tk.LEFT)
        vsb = ttk.Scrollbar(
            self.list_frame, orient="vertical", command=self.timer_tree.yview
        )
        self.timer_tree.configure(yscrollcommand=vsb.set)
        vsb.pack(side=tk.RIGHT, fill=tk.Y)

    # ================= Logic =================
    def _validate_numeric_key(self, event) -> str | None:
        if event.char and not event.char.isdigit():
            return "break"
        return None

    def _on_entry_focus(self, event) -> None:
        event.widget.select_range(0, tk.END)

    def _get_valid_entry(self, widget: ttk.Entry, min_val: int, max_val: int) -> int:
        try:
            value = int(widget.get())
            if not (min_val <= value <= max_val):
                raise ValueError
            return value
        except Exception:
            widget.delete(0, tk.END)
            widget.insert(0, "0")
            return 0

    def _update_mode_panels(self) -> None:
        if self.timer_mode.get() == "countup":
            self.countdown_frame.pack_forget()
            self.status_label.config(text="就绪")
        else:
            # show countdown & prefill from current_seconds if any
            self.countdown_frame.pack(padx=10, pady=5, fill=tk.X)
            total = int(self.current_seconds)
            h, m, s = total // 3600, (total % 3600) // 60, total % 60
            for entry, val in (
                (self.hours_entry, h),
                (self.minutes_entry, m),
                (self.seconds_entry, s),
            ):
                entry.delete(0, tk.END)
                entry.insert(0, str(val))
        self._toggle_buttons(self.timer.running)

    def _toggle_buttons(self, running: bool) -> None:
        self.start_btn.config(state=tk.DISABLED if running else tk.NORMAL)
        self.pause_btn.config(state=tk.NORMAL if running else tk.DISABLED)
        self.stop_btn.config(state=tk.NORMAL if running else tk.DISABLED)
        self.pause_btn.config(text="继续" if self.timer.paused else "暂停")

    # ----- Timer callbacks -----
    def _update_display(self, seconds: float) -> None:
        self.current_seconds = max(0.0, float(seconds))
        total = int(self.current_seconds)
        h, rem = divmod(total, 3600)
        m, s = divmod(rem, 60)
        self.time_label.config(text=f"{h:02d}:{m:02d}:{s:02d}")
        if self.timer.running:
            mode_text = (
                "正计时中..." if self.timer_mode.get() == "countup" else "倒计时中..."
            )
            self.status_label.config(text=mode_text)

    def _on_complete(self) -> None:
        self.status_label.config(text="计时完成！")
        if self.timer_mode.get() == "countdown":
            self._toggle_buttons(False)

    # ----- Actions -----
    def start_timer(self) -> None:
        try:
            if self.timer_mode.get() == "countdown":
                h = self._get_valid_entry(self.hours_entry, 0, 23)
                m = self._get_valid_entry(self.minutes_entry, 0, 59)
                s = self._get_valid_entry(self.seconds_entry, 0, 59)
                total = h * 3600 + m * 60 + s
                if total <= 0:
                    messagebox.showinfo("提示", "请输入大于0的倒计时时间")
                    return
                # Use single segment countdown for now
                self.timer.countdown([(h, m, s)])
                self.status_label.config(text="倒计时中...")
            else:
                self.timer.start()
                self.status_label.config(text="正计时中...")
            self._toggle_buttons(True)
        except Exception as e:
            messagebox.showerror("错误", f"操作失败: {e}")

    def pause_timer(self) -> None:
        try:
            if self.timer.paused:
                # resume
                self.timer.resume()
                cur = (
                    "countdown" if self.countdown_frame.winfo_ismapped() else "countup"
                )
                self.status_label.config(
                    text=("正计时中..." if cur == "countup" else "倒计时中...")
                )
                self.pause_btn.config(text="暂停")
            else:
                self.timer.pause()
                self.status_label.config(text="已暂停")
                self.pause_btn.config(text="继续")
        except Exception as e:
            messagebox.showerror("错误", f"操作失败: {e}")

    def stop_timer(self) -> None:
        try:
            current_seconds = self.current_seconds
            self.timer.stop()
            if current_seconds > 0:
                self._show_save_dialog(current_seconds)
            else:
                self._reset_after_stop()
        except Exception as e:
            messagebox.showerror("错误", f"操作失败: {e}")

    def _show_save_dialog(self, seconds: float) -> None:
        save_dialog = tk.Toplevel(self.root)
        save_dialog.title("保存确认")
        save_dialog.geometry("300x100")
        save_dialog.resizable(False, False)
        # center over main window
        try:
            main_window_x = self.root.winfo_x()
            main_window_y = self.root.winfo_y()
            main_window_width = self.root.winfo_width()
            dialog_x = main_window_x + (main_window_width - 300) // 2
            save_dialog.geometry(f"+{dialog_x}+{main_window_y+50}")
        except Exception:
            pass
        msg = f"当前计时：{self.time_label.cget('text')} 是否保存本次计时？"
        ttk.Label(save_dialog, text=msg).pack(pady=10)
        btn_frame = ttk.Frame(save_dialog)
        btn_frame.pack(pady=5)
        ttk.Button(
            btn_frame,
            text="保存",
            command=lambda: self._handle_stop_save(save_dialog, seconds),
        ).pack(side=tk.LEFT, padx=10)
        ttk.Button(
            btn_frame,
            text="不保存",
            command=lambda: self._handle_stop_discard(save_dialog),
        ).pack(side=tk.LEFT, padx=10)

    def _handle_stop_save(self, dialog: tk.Toplevel, seconds: float) -> None:
        try:
            total = int(seconds)
            h, rem = divmod(total, 3600)
            m, s = divmod(rem, 60)
            db_save_timer(h, m, s)
            self._refresh_timer_list()
            if self.on_data_changed:
                self.on_data_changed()
        finally:
            dialog.destroy()
            self._reset_after_stop()

    def _handle_stop_discard(self, dialog: tk.Toplevel) -> None:
        dialog.destroy()
        self._reset_after_stop()

    def _reset_after_stop(self) -> None:
        self._toggle_buttons(False)
        self.time_label.config(text="00:00:00")
        self.status_label.config(text="就绪")
        if self.timer_mode.get() == "countdown":
            for e in (self.hours_entry, self.minutes_entry, self.seconds_entry):
                e.delete(0, tk.END)
                e.insert(0, "0")

    def save_timer(self) -> None:
        try:
            if self.timer_mode.get() == "countup":
                total = int(self.timer.elapsed_seconds)
                if total <= 0:
                    raise ValueError("请先启动正计时")
                h, rem = divmod(total, 3600)
                m, s = divmod(rem, 60)
            else:
                h = self._get_valid_entry(self.hours_entry, 0, 23)
                m = self._get_valid_entry(self.minutes_entry, 0, 59)
                s = self._get_valid_entry(self.seconds_entry, 0, 59)
                if (h + m + s) == 0:
                    raise ValueError("时间不能全为0")
            db_save_timer(h, m, s)
            self._refresh_timer_list()
            if self.on_data_changed:
                self.on_data_changed()
            messagebox.showinfo("成功", f"已保存: {h:02d}:{m:02d}:{s:02d}")
        except Exception as e:
            messagebox.showerror("错误", str(e))

    def _refresh_timer_list(self) -> None:
        # clear current
        for item in self.timer_tree.get_children():
            self.timer_tree.delete(item)
        try:
            for rec in get_timers():
                time_str = f"{rec.hours:02d}:{rec.minutes:02d}:{rec.seconds:02d}"
                try:
                    created_str = rec.created_at.strftime("%Y-%m-%d %H:%M:%S")
                except Exception:
                    created_str = str(rec.created_at)
                self.timer_tree.insert(
                    "", "end", values=(time_str, created_str), iid=str(rec.id)
                )
        except Exception as e:
            messagebox.showerror("错误", f"加载记录失败: {e}")

    def delete_timer(self) -> None:
        try:
            selection = self.timer_tree.selection()
            if not selection:
                messagebox.showinfo("提示", "请先选择要删除的记录")
                return
            if not messagebox.askyesno(
                "确认", f"确定删除选中的 {len(selection)} 条记录吗？"
            ):
                return
            deleted = 0
            for iid in selection:
                try:
                    delete_timer_by_id(int(iid))
                    deleted += 1
                except Exception as e:
                    messagebox.showerror("删除失败", f"ID {iid} 删除失败：{e}")
            self._refresh_timer_list()
            if self.on_data_changed:
                self.on_data_changed()
            messagebox.showinfo("完成", f"已删除 {deleted} 条记录")
        except Exception as e:
            messagebox.showerror("错误", f"删除失败：{e}")

    def clear_timers(self) -> None:
        if messagebox.askyesno("确认", "确定要清空所有记录吗？"):
            db_clear_timers()
            self._refresh_timer_list()
            if self.on_data_changed:
                self.on_data_changed()
